package com.mytx.sso.scheduled;

import com.alibaba.fastjson.JSONObject;
import com.mytx.common.constant.Constant;
import com.mytx.common.pojo.RedisLock;
import com.mytx.common.utils.DateUtils;
import com.mytx.mapper.CouponMapper;
import com.mytx.mapper.UserMapper;
import com.mytx.pojo.Coupon;
import com.mytx.search.SearchService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@Component
public class ScheduledTask {
    Logger logger = LoggerFactory.getLogger(ScheduledTask.class);
    private static final long QUERY_COUNT = 200;

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    CouponMapper couponMapper;

    @Autowired
    UserMapper userMapper;

    @Autowired
    SearchService searchService;

    /**
     * 定时去redis中读取金币红包的缓存，更新状态为过期，并且持久化到mysql
     */
     // @Scheduled(fixedRate = 1000 * 60 * 3)//每个小时执行一次
     @Scheduled(cron = "0 59 0-23 * * ? ")//0-24小时，每个小时的59分钟开始执行
  //  @Scheduled(cron = "0 55 16 ? * *")
    public void couponScheduledTask() {
       // Date currentDate = new Date();
        Date currentDate = DateUtils.getDate(1);

        //输出年月日小时格式
        String formatDate = DateUtils.formatDate(currentDate, "yyyy-MM-dd-HH");
        String key = Constant.COUPON_SET + formatDate;

       // key = "COUPON_SET:2019-05-15-16";

        boolean haveMoreData = false;
        Long size = redisTemplate.opsForSet().size(key);
        if (size != null && size > 0) {
            haveMoreData = true;
        }
            logger.info("couponScheduledTask：红包到期定时任务执行, key:{},size:{}",key,size);

        while (haveMoreData) {
            long count;
            if (size > QUERY_COUNT) {
                size = size - QUERY_COUNT;
                count = QUERY_COUNT;
            } else {
                count = size;
                haveMoreData = false;
            }
            List<String> couponIdList = redisTemplate.opsForSet().pop(key, count);
            if (couponIdList == null || couponIdList.size() == 0) {
                logger.error("coinCouponScheduledTask：金币红包到期，批量更新到mysql--没有需要更新的数据");
                break;
            }
            List<String> couponKeyList = new ArrayList<>();
            for (String couponId : couponIdList) {
                couponKeyList.add(Constant.COUPON_RECORD + couponId);
            }


            List<Coupon> couponList = redisTemplate.opsForValue().multiGet(couponKeyList);
            List<Coupon> multipleCouponList = new ArrayList<>();
            for (int i = 0; i < couponList.size(); i++) {
                Coupon coupon = couponList.get(i);
                coupon.setStatus(Constant.COUPON_STATUS_EXPIRED);
                //把过期没领取的红包金额，返回到用户余额

                String uid = coupon.getuId();
                RedisLock lock = new RedisLock(redisTemplate, Constant.COUPON_LOCK + coupon.getId());
                try {
                    if (!lock.lock()) {
                        logger.error("couponScheduledTask：红包过期定时任务获取锁失败 couponId:{}", coupon.getId());
                        break;
                    }
                    //返还用户发送红包的金额
                    BigDecimal mysqlBalance = BigDecimal.ZERO;
                    BigDecimal retrunAmount=BigDecimal.ZERO;
                    if (coupon.getType() == Constant.COUPON_TYPE_SINGLE) {
                        retrunAmount=coupon.getAmount();
                        mysqlBalance = userMapper.incrementBalance(uid, retrunAmount);
                    } else if (coupon.getType() == Constant.COUPON_TYPE_MULTIPLE_AVERAGE || coupon.getType() == Constant.COUPON_TYPE_MULTIPLE_RANDOM) {
                        couponList.remove(i);
                        multipleCouponList.add(coupon);
                        i--;//因为couponList 去除了一堆红包，所以需要 i - -,不然会跳过一个红包
                        retrunAmount=coupon.getBalance();
                        mysqlBalance = userMapper.incrementBalance(uid, retrunAmount);
                        //一对多红包需要清理所依附的主题或者直播间
                        String topicId = coupon.getTopicId();
                        if (StringUtils.isNotBlank(topicId)) {
                            searchService.deleteCoupon(topicId);
                        } else {
                            String liveRoomId = coupon.getLiveRoomId();
                            if (StringUtils.isNotBlank(liveRoomId)) {
                                redisTemplate.opsForHash().delete(Constant.LIVE_ROOM + liveRoomId, "coupon");
                            }
                        }
                        //清除领取记录
                        redisTemplate.delete(Constant.COUPON_RECEIVED_RECORD + coupon.getId());
                    }

                    //清除定时任务所需的SET缓存
                    redisTemplate.opsForSet().remove(key, coupon.getId());
                    //清除红包缓存
                    redisTemplate.delete(Constant.COUPON_RECORD + coupon.getId());
                    //更新用户余额缓存
                    redisTemplate.opsForHash().put(Constant.USER_SESSION + uid, Constant.BALANCE, mysqlBalance);
                    logger.info("couponScheduledTask：红包到期自动撤回，余额增加， uid:{},couponId:{},amount:{},balance:{}", uid, coupon.getId(), retrunAmount, mysqlBalance);
                    //  通知红包返还，更新账户余额
                    JSONObject info = new JSONObject();
                    info.put("uId", uid);
                    redisTemplate.convertAndSend(Constant.NOTIFY_SYNC_USER_INFO, info);
                } catch (Exception e) {
                    logger.error("couponScheduledTask" + e.getMessage());
                } finally {
                    lock.unlock();
                }
            }
//            Long delete = redisTemplate.delete(couponKeyList);
//            if (delete != couponKeyList.size()) {
//                logger.error("couponScheduledTask：清理红包缓存没彻底，delete:{},couponKeyListSize:{}", delete, couponKeyList.size());
//            }
            //批量更新一对一红包状态
            if (couponList.size() != 0) {
                couponMapper.updateBatch2(couponList, Constant.COUPON_STATUS_EXPIRED);
            }
            //批量更新一对多红包余额以及状态
            if (multipleCouponList.size() != 0) {
                couponMapper.updateBatch5(multipleCouponList, Constant.COUPON_STATUS_EXPIRED);
            }

        }
    }


}
